using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Dss.Core;
using Microsoft.Dss.Core.Attributes;
using System.ComponentModel;

namespace VEXRobotics
{
    /// <summary>
    /// Type of sensor attached to the IO Port
    /// </summary>
    [DataContract]
    [Description("Motor port used.")]
    public enum MotorPort
    {
        /// <summary>
        /// No port
        /// </summary>
        [Description("No port used")]
        MotorPort_None = 0,

        /// <summary>
        /// Motor Port 1
        /// </summary>
        [Description("Motor Port 1")]
        MotorPort_1 = 1,

        /// <summary>
        /// Motor Port 2
        /// </summary>
        [Description("Motor Port 2")]
        MotorPort_2 = 2,

        /// <summary>
        /// Motor Port 3
        /// </summary>
        [Description("Motor Port 3")]
        MotorPort_3 = 3,

        /// <summary>
        /// Motor Port 4
        /// </summary>
        [Description("Motor Port 4")]
        MotorPort_4 = 4,

        /// <summary>
        /// Motor Port 5
        /// </summary>
        [Description("Motor Port 5")]
        MotorPort_5 = 5,

        /// <summary>
        /// Motor Port 6
        /// </summary>
        [Description("Motor Port 6")]
        MotorPort_6 = 6,

        /// <summary>
        /// Motor Port 7
        /// </summary>
        [Description("Motor Port 7")]
        MotorPort_7 = 7,

        /// <summary>
        /// Motor Port 8
        /// </summary>
        [Description("Motor Port 8")]
        MotorPort_8 = 8,
    }

    /// <summary>
    /// Motor values (Range -127 to 127)
    /// </summary>
    [DataContract]
    public class MotorData
    {
        private string _type = "None";
        private int _value = 127;

        /// <summary>
        /// Type of 'motor' connected to the port
        /// </summary>
        [DataMember]
        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }
        /// <summary>
        /// Current value set for the motor
        /// </summary>
        [DataMember]
        public int Value
        {
            get { return _value; }
            set { _value = value; }
        }
    }

    [DataContract]
    public class MotorConfig : IDssSerializable, ICloneable
    {
        private MotorData[] _motors;

        /// <summary>
        /// Default contructor
        /// </summary>
        public MotorConfig()
        {
            _motors = new MotorData[8];
            _motors[0] = new MotorData();
            _motors[1] = new MotorData();
            _motors[2] = new MotorData();
            _motors[3] = new MotorData();
            _motors[4] = new MotorData();
            _motors[5] = new MotorData();
            _motors[6] = new MotorData();
            _motors[7] = new MotorData();
        }

        /// <summary>
        /// The Motor array
        /// </summary>
        [DataMember()]
        public MotorData[] Motors
        {
            get { return this._motors; }
            set { this._motors = value; }
        }


        #region ICloneable Members

        /// <summary>
        /// Define how to clone ourselves
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            MotorConfig config = new MotorConfig();
            for (int i = 0; i < _motors.Length; ++i)
            {
                config.Motors[i].Type = this.Motors[i].Type;
                config.Motors[i].Value = this.Motors[i].Value;
            }
            return config;
        }

        #endregion

        #region IDssSerializable

        /// <summary>
        /// Copy To state
        /// </summary>
        public virtual void CopyTo(IDssSerializable target)
        {
            MotorConfig typedTarget = target as MotorConfig;

            if (typedTarget == null)
                throw new ArgumentException("CopyTo({0}) requires type {0}", this.GetType().FullName);

            for(int i=0; i<Motors.Length; ++i)
            {
                typedTarget.Motors[i].Type = this.Motors[i].Type;
                typedTarget.Motors[i].Value = this.Motors[i].Value;
            }
        }

        /// <summary>
        /// Serialize
        /// </summary>
        public virtual void Serialize(System.IO.BinaryWriter writer)
        {
            for (int i = 0; i < Motors.Length; ++i)
            {
                writer.Write(this.Motors[i].Type);
                writer.Write(this.Motors[i].Value);
            }
        }

        /// <summary>
        /// Deserialize
        /// </summary>
        public virtual object Deserialize(System.IO.BinaryReader reader)
        {
            for (int i = 0; i < Motors.Length; ++i)
            {
                this.Motors[i].Type = reader.ReadString();
                this.Motors[i].Value = reader.ReadInt32();
            }
            return this;
        }
        #endregion
    }
}
